package com.imooc.service.impl;

import com.imooc.dto.OrderDto;
import com.imooc.enums.ResultEnum;
import com.imooc.exception.SellException;
import com.imooc.service.OrderService;
import com.imooc.service.PayService;
import com.imooc.utils.JsonUtils;
import com.imooc.utils.MathUtils;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.model.RefundRequest;
import com.lly835.bestpay.model.RefundResponse;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 功能描述: <br>
 * (支付模块service)
 *
 * @Author:Mr. xyb
 * @Date: 2018/5/18 17:13
 * @since: 1.8.0
 * @version: 1.0.0
 */
@Service
@Slf4j
public class PayServiceImpl implements PayService {


    private static final String ORDER_NAME = "微信点餐订单";

    @Autowired
    private BestPayServiceImpl bestPayService;

    @Autowired
    private OrderService orderService;

    /**
     * 发起支付 创建支付数据
     *
     * @param orderDto 订单数据
     * @return
     */
    @Override
    public PayResponse create(OrderDto orderDto) {
        /*创建支付请求参数*/
        PayRequest payRequest = new PayRequest();
        /*设置请求参数的值*/
        payRequest.setOpenid(orderDto.getBuyerOpenid());// openid
        payRequest.setOrderAmount(orderDto.getOrderAmount().doubleValue());// 总金额
        payRequest.setOrderId(orderDto.getOrderId());// 订单id
        payRequest.setOrderName(ORDER_NAME);// 订单名称
        payRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);// 支付的方式
        log.info("【微信支付】发起支付request={}", JsonUtils.toJson(payRequest));
        PayResponse payResponse = bestPayService.pay(payRequest);// 调用支付
        log.info("【微信支付】发起支付response={}", JsonUtils.toJson(payResponse));
        return payResponse;
    }

    /**
     * 支付结束回调函数
     *
     * @param notifyData xml格式的数据
     * @return
     */
    @Override
    public PayResponse notify(String notifyData) {
        //1. 验证签名
        //2. 支付的状态
        //3. 支付金额
        //4. 支付人
        PayResponse payResponse = bestPayService.asyncNotify(notifyData);
        log.info("【微信支付】异步通知，payResponse={}", payResponse);
        // 查询订单
        OrderDto orderDto = orderService.findOne(payResponse.getOrderId());
        // 判断订单是否存在
        if (orderDto == null) {
            log.error("【微信支付】异步通知，订单不存在，orderId={}", payResponse.getOrderId());
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }
        // 判断订单金额与微信支付实际是否一致
        if (!MathUtils.equals(orderDto.getOrderAmount().doubleValue(), payResponse.getOrderAmount())) {
            log.error("【微信支付】异步通知，订单金额不一致，orderId={},微信通知金额={},系统金额={}",
                    payResponse.getOrderId(),
                    payResponse.getOrderAmount(),
                    orderDto.getOrderAmount());
            throw new SellException(ResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR);
        }
        /*修改订单支付状态*/
        orderService.paid(orderDto);
        return payResponse;
    }

    /**
     * (退款)
     *
     * @param orderDto
     * @return
     */
    @Override
    public RefundResponse refund(OrderDto orderDto) {

        /*拼接参数*/
        RefundRequest refundRequest = new RefundRequest();
        refundRequest.setOrderId(orderDto.getOrderId());// 订单id
        refundRequest.setOrderAmount(orderDto.getOrderAmount().doubleValue());// 订单总金额
        refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);// 支付方式（微信公众账号支付）
        log.info("【微信退款】request={}", JsonUtils.toJson(refundRequest));

        /*发起退款*/
        RefundResponse refundResponse = bestPayService.refund(refundRequest);
        log.info("【微信退换】response={}", JsonUtils.toJson(refundResponse));
        return refundResponse;
    }
}
